home *** CD-ROM | disk | FTP | other *** search
- ╒═══════════════════════════════╕
- │ W E L C O M E │
- │ To the VGA Trainer Program │ │
- │ By │ │
- │ DENTHOR of ASPHYXIA │ │ │
- ╘═══════════════════════════════╛ │ │
- ────────────────────────────────┘ │
- ────────────────────────────────┘
-
- --==[ PART 15 ]==--
-
-
-
- =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- ■ Introduction
-
- Hello again. As you can see, this tut is very soon after the last one.
- This is because of two reasons ... 1) The PCGPE ][ will be out soon, so
- I thought I would make sure I have more then just four new trainers for it,
- and 2) I am usually so late between tuts, I thought I would make up for it.
-
- There is a discussion going on in Usenet, mostly saying that trainers etc.
- should be written a bit more formally and none of this gay banter and
- familiar language should be used. My "quotes" would definately be out ;-)
- But, until I get paid for doing this (and there don't seem to be any takers
- on that score), I will continue to write in this manner. My apologies to those
- who dont like this, but hey, its free, what did you expect?
-
- This trainer is on plasmas, and the sample program actually became quite large,
- mostly due to the fact that there was some plasma stuff I wanted to try out.
-
- The concept is very simple, at least for this plasma, so you shouldn't have
- any problems understanding it ... AFTER you have read the text file ...
- jumping straight into the source may be hazardous to your brain.
-
- Plasmas are a great way to wow your friends by their wierd shapes and forms.
- I was at one stage going to write a game where the bad guy just had two
- circular plasmas instead of eyes... I am sure you will find creative and
- inventive new ways of doing and using plasmas.
-
-
- If you would like to contact me, or the team, there are many ways you
- can do it : 1) Write a message to Grant Smith/Denthor/Asphyxia in private mail
- on the ASPHYXIA BBS.
- 2) Write to : Grant Smith
- P.O.Box 270 Kloof
- 3640
- Natal
- South Africa
- 3) Call me (Grant Smith) at (031) 73 2129 (leave a message if you
- call during varsity). Call +27-31-73-2129 if you call
- from outside South Africa. (It's YOUR phone bill ;-))
- 4) Write to denthor@beastie.cs.und.ac.za in E-Mail.
- 5) Write to asphyxia@beastie.cs.und.ac.za to get to all of
- us at once.
-
- NB : If you are a representative of a company or BBS, and want ASPHYXIA
- to do you a demo, leave mail to me; we can discuss it.
- NNB : If you have done/attempted a demo, SEND IT TO ME! We are feeling
- quite lonely and want to meet/help out/exchange code with other demo
- groups. What do you have to lose? Leave a message here and we can work
- out how to transfer it. We really want to hear from you!
-
-
-
- =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- ■ How do plasmas work?
-
- I will only cover one type of plasma here ... a realtime plasma of course.
- Other types of plasmas include a static picture with a pallette rotation...
-
- When you get right down to it, this method of realtime plasmas is merely an
- intersection of four COS waves. We get our color at a particular point by
- saying :
- col := costbl[one]+costbl[two]+costbl[three]+costbl[four];
-
- The trick is getting the four indexes of that cos table array to create
- something that looks nice. This is how we organise it : Have two of them
- being indexes for vertical movement and two of them being indexes for
- horizontal movement.
-
- This means that by changing these values we can move along the plasma. To
- draw an individual screen, we pass the values of the four to another four
- so that we do not disturb the origional values. For every pixel across, we
- add values to the first two indexes, then display the next pixel. For
- every row down, we add values to the second two indexes. Sound complex
- enough? Good, because that what we want, a complex shape on the screen.
-
- By altering the origional four values, we can get all sorts of cool movement
- and cycling of the plasma. The reason we use a cos table is as follows :
- a cos table has a nice curve in the value of the numbers ... when you
- put two or more together, it is possible to get circular pictures ...
- circles are hard to do on a computer, so this makes it a lot easier...
-
- Okay, now you can have a look at the source file, all I do is put the above
- into practice. I did add one or two things though ...
-
- Background : This is just a large array, with the values in the array being
- added to the plasma at that pixel.
-
- Psychadelic : This cycles through about 7000 colors instead of just rotating
- through the base 256.
-
-
- =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- ■ Clever fading
-
- You will notice when the sample program fades in and out that the colors
- all reach their destination at the same time ... it other words, they don't
- all increment by one until they hit the right color then stop. When done
- in that way the fading does not look as professional.
-
- Here is how we do a step-crossfade.
-
- Each r,g,b value can be between 0 and 64. Have the pallette we want to get
- to in bob and the temporary pallette in bob2. For each step, from 0 to 63
- do the following :
- bob2[loop1].r:=bob[loop1].r*step/64;
-
- That means if we are halfway through the crossfade (step=32) and the red
- value is meant to get to 16, our equation looks like this :
- r:=16*32/64
- r=8
-
- Which is half of the way to where it wants to be. This means all colors will
- fade in/out with the same ratios... and look nicer.
-
-
- =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- ■ Rotating the pallette
-
- I have done this one before I think .. here it is ...
-
- move color 0 into temp
-
- move color 1 into color 0
- move color 2 into color 1
- move color 3 into color 2
- and so on till color 255
-
- move temp into color 255
-
- And you pallette is rotating. Easy huh? Recheck tut 2 for more info on
- pallette rotation
-
- =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- ■ In closing
-
- The text file was a bit short this time, but that is mostly because the
- sample file is self explanitory. The file can however be speeded up, and
- of course you can add certain things which will totally change the look
- of the plasma.
-
- As always, I am on the lookout for more ideas for future tuts, if you have
- some, mail me!
-
- No quote today, this lan doesn't encourage creative thinking ;) However,
- there will be quotes in future as I have been told that some people like
- them. Even Pipsy said this while we were playing Ctrl-Alt-Del (two player
- game, one has to hit ctrl and alt as the other hits del, and the person
- hitting the del has to do it quickly so that the computer doesnt reboot.
- If the computer reboots the person who was hitting ctrl and alt has won.
- I thought I was doing really badly against Pipsy until I found out that the
- computer had frozen ;-))
-
- Byeeee....
- - Denthor
- 14:11
- 16-9-94
-
-
- The following are official ASPHYXIA distribution sites :
-
- ╔══════════════════════════╦════════════════╦═════╗
- ║BBS Name ║Telephone No. ║Open ║
- ╠══════════════════════════╬════════════════╬═════╣
- ║ASPHYXIA BBS #1 ║+27-31-765-5312 ║ALL ║
- ║ASPHYXIA BBS #2 ║+27-31-765-6293 ║ALL ║
- ║C-Spam BBS ║410-531-5886 ║ALL ║
- ║POP! ║+27-12-661-1257 ║ALL ║
- ║Soul Asylum ║+358-0-5055041 ║ALL ║
- ║Wasted Image ║407-838-4525 ║ALL ║
- ╚══════════════════════════╩════════════════╩═════╝
-
- Leave me mail if you want to become an official Asphyxia BBS
- distribution site.
- {$X+}
- USES crt;
-
- TYPE RGBType = Record
- R, G, B : Byte;
- End;
- PalType = Array[0..255] of RGBType;
-
- VAR bob,bob2:paltype; { Two pallettes, current and temporary }
- biiiigpallette : array [1..6656] of RGBType; { A massive pallette for the
- psychadelic effect }
- start:integer; { Where in the Biiiig pallette are we? }
- Effect,Background:Boolean; { Configuration of effects }
-
- costbl : Array [0..255] of byte; { cos table lookup }
- mov1,mov2,mov3,mov4 : byte; { current positions }
- bkg : array [1..50,1..80] of byte; { The pic in the background }
-
-
-
- {──────────────────────────────────────────────────────────────────────────}
- procedure PAL(Col,R,G,B : Byte); assembler;
- { This sets the Red, Green and Blue values of a certain color }
- asm
- mov dx,3c8h
- mov al,[col]
- out dx,al
- inc dx
- mov al,[r]
- out dx,al
- mov al,[g]
- out dx,al
- mov al,[b]
- out dx,al
- end;
-
- {──────────────────────────────────────────────────────────────────────────}
- Procedure SetAllPal(Var Palette : PalType); Assembler;
- { This dumps the pallette in our variable onto the screen, fast }
- Asm
- push ds
- lds si, Palette
- mov dx, 3c8h
- mov al, 0
- out dx, al
- inc dx
- mov cx, 768
- rep outsb
- pop ds
- End;
-
- {──────────────────────────────────────────────────────────────────────────}
- Procedure Makerun (r,g,b:integer);
- { This creates a ramp of colors and puts them into biiiigpallette }
- VAR loop1:integer;
- BEGIN
- for loop1:=start to start+127 do BEGIN
- if r=1 then
- biiiigpallette[loop1].r:=63-(loop1-start) div 4 else
- if r=2 then
- biiiigpallette[loop1].r:=(loop1-start) div 4 else
- biiiigpallette[loop1].r:=0;
-
- if g=1 then
- biiiigpallette[loop1].g:=63-(loop1-start) div 4 else
- if g=2 then
- biiiigpallette[loop1].g:=(loop1-start) div 4 else
- biiiigpallette[loop1].g:=0;
-
- if b=1 then
- biiiigpallette[loop1].b:=63-(loop1-start) div 4 else
- if b=2 then
- biiiigpallette[loop1].b:=(loop1-start) div 4 else
- biiiigpallette[loop1].b:=0;
- END;
-
- for loop1:=start+128 to start+255 do BEGIN
- if r=2 then
- biiiigpallette[loop1].r:=63-(loop1-start) div 4 else
- if r=1 then
- biiiigpallette[loop1].r:=(loop1-start) div 4 else
- biiiigpallette[loop1].r:=0;
-
- if g=2 then
- biiiigpallette[loop1].g:=63-(loop1-start) div 4 else
- if g=1 then
- biiiigpallette[loop1].g:=(loop1-start) div 4 else
- biiiigpallette[loop1].g:=0;
-
- if b=2 then
- biiiigpallette[loop1].b:=63-(loop1-start) div 4 else
- if b=1 then
- biiiigpallette[loop1].b:=(loop1-start) div 4 else
- biiiigpallette[loop1].b:=0;
- END;
- start:=start+256;
- END;
-
-
- {──────────────────────────────────────────────────────────────────────────}
- Procedure init;
- VAR loop1,loop2,r,g,b:integer;
- f:text;
- ch:char;
-
- Function rad (theta : real) : real; { Converts degrees to radians }
- BEGIN
- rad := theta * pi / 180
- END;
-
- BEGIN
- write ('Do you want the Psychadelic effect? ');
- repeat
- ch:=upcase(readkey);
- until ch in ['Y','N'];
- if ch='Y' then BEGIN
- Writeln ('Yeah!');
- effect:=true;
- END else BEGIN
- Writeln ('Nah');
- effect:=false;
- END;
- writeln;
- while keypressed do readkey;
- write ('Do you want the background? ');
- repeat
- ch:=upcase(readkey);
- until ch in ['Y','N'];
- if ch='Y' then BEGIN
- Writeln ('Yeah!');
- background:=true;
- END else BEGIN
- Writeln ('Nah');
- background:=false;
- END;
- writeln;
- while keypressed do readkey;
- writeln ('Hit any key to continue...');
- readkey;
- while keypressed do readkey;
- asm
- mov ax,0013h
- int 10h { Enter mode 13 }
- cli
- mov dx,3c4h
- mov ax,604h { Enter unchained mode }
- out dx,ax
- mov ax,0F02h { All planes}
- out dx,ax
-
- mov dx,3D4h
- mov ax,14h { Disable dword mode}
- out dx,ax
- mov ax,0E317h { Enable byte mode.}
- out dx,ax
- mov al,9
- out dx,al
- inc dx
- in al,dx
- and al,0E0h { Duplicate each scan 8 times.}
- add al,7
- out dx,al
- end;
-
- fillchar (bob2,sizeof(bob2),0); { Clear pallette bob2 }
- setallpal (bob2);
-
- start:=0;
- r:=0;
- g:=0;
- b:=0;
- Repeat
- makerun (r,g,b);
- b:=b+1;
- if b=3 then BEGIN
- b:=0;
- g:=g+1;
- END;
- if g=3 then BEGIN
- g:=0;
- r:=r+1;
- END;
- until (r=2) and (g=2) and (b=2);
- { Set up our major run of colors }
-
- start:=0;
- if not effect then BEGIN
- for loop1:=0 to 128 do BEGIN
- bob[loop1].r:=63-loop1 div 4;
- bob[loop1].g:=0;
- bob[loop1].b:=loop1 div 4;
- END;
- for loop1:=129 to 255 do BEGIN
- bob[loop1].r:=loop1 div 4;
- bob[loop1].g:=0;
- bob[loop1].b:=63-loop1 div 4;
- END;
- END else
- for loop1:=0 to 255 do bob[loop1]:=biiiigpallette[loop1];
-
- { Set up a nice looking pallette ... we alter color 0, so the border will
- be altered. }
-
- For loop1:=0 to 255 do
- costbl[loop1]:=round (cos (rad (loop1/360*255*2))*31)+32;
- { Set up our lookup table...}
-
- fillchar (bkg,sizeof(bkg),0);
- assign (f,'a:bkg.dat');
- reset (f);
- for loop1:=1 to 50 do BEGIN
- for loop2:=1 to 80 do BEGIN
- read (f,ch);
- if ord (ch)<>48 then
- bkg[loop1,loop2]:=ord (ch)-28;
- END;
- readln (f);
- END;
- close (f);
- { Here we read in our background from the file bkg.dat }
- END;
-
-
- {──────────────────────────────────────────────────────────────────────────}
- Procedure DrawPlasma;
- { This procedure draws the plasma onto the screen }
- VAR loop1,loop2:integer;
- tmov1,tmov2,tmov3,tmov4:byte; { Temporary variables, so we dont destroy
- the values of our main variables }
- col:byte;
- where:word;
- BEGIN
- tmov3:=mov3;
- tmov4:=mov4;
- where:=0;
- asm
- mov ax,0a000h
- mov es,ax { In the two loops that follow, ES is not altered so
- we just set it once, now }
- end;
- For loop1:=1 to 50 do BEGIN { Fifty rows down }
- tmov1:=mov1;
- tmov2:=mov2;
- for loop2:=1 to 80 do BEGIN { Eighty columns across }
- if background then
- col:=costbl[tmov1]+costbl[tmov2]+costbl[tmov3]+costbl[tmov4]+costbl[loop1]+costbl[loop2]+bkg[loop1,loop2]
- else
- col:=costbl[tmov1]+costbl[tmov2]+costbl[tmov3]+costbl[tmov4]+costbl[loop1]+costbl[loop2];
- { col = Intersection of numerous cos waves }
- asm
- mov di,where { di is killed elsewhere, so we need to restore it}
- mov al,col
- mov es:[di],al { Place col at ES:DI ... sequential across the screen}
- end;
- where:=where+1; { Inc the place to put the pixel }
- tmov1:=tmov1+4;
- tmov2:=tmov2+3; { Arb numbers ... replace to zoom in/out }
- END;
- tmov3:=tmov3+4;
- tmov4:=tmov4+5; { Arb numbers ... replace to zoom in/out }
- END;
- END;
-
-
- {──────────────────────────────────────────────────────────────────────────}
- Procedure MovePlasma;
- { This procedure moves the plasma left/right/up/down }
- BEGIN
- mov1:=mov1-4;
- mov3:=mov3+4;
- mov1:=mov1+random (1);
- mov2:=mov2-random (2);
- mov3:=mov3+random (1);
- mov4:=mov4-random (2); { Movement along the plasma + noise}
- END;
-
- {──────────────────────────────────────────────────────────────────────────}
- procedure WaitRetrace; assembler;
- { This waits for a vertical retrace to reduce snow on the screen }
- label
- l1, l2;
- asm
- mov dx,3DAh
- l1:
- in al,dx
- test al,8
- jnz l1
- l2:
- in al,dx
- test al,8
- jz l2
- end;
-
- {──────────────────────────────────────────────────────────────────────────}
- Procedure fadeupone (stage:integer);
- { This procedure fades up the pallette bob2 by one increment and sets the
- onscreen pallette. Colors are increased proportionally, do that all colors
- reach their destonation at the same time }
- VAR loop1:integer;
- temp:rgbtype;
- BEGIN
- if not effect then move (bob[0],temp,3);
- move (bob[1],bob[0],765);
- if effect then move (biiiigpallette[start],bob[255],3) else
- move (temp,bob[255],3);
- start:=start+1;
- if start=6657 then start:=0;
- { Rotate the pallette }
-
- for loop1:=0 to 255 do BEGIN
- bob2[loop1].r:=integer(bob[loop1].r*stage div 64);
- bob2[loop1].g:=integer(bob[loop1].g*stage div 64);
- bob2[loop1].b:=integer(bob[loop1].b*stage div 64);
- END; { Fade up the pallette }
- setallpal (bob2);
- END;
-
-
- {──────────────────────────────────────────────────────────────────────────}
- Procedure Shiftpallette;
- { This rotates the pallette, and introduces new colors if the psychadelic
- effect has been chosen }
- VAR loop1:integer;
- temp:rgbtype;
- BEGIN
- if not effect then move (bob2[0],temp,3);
- move (bob2[1],bob2[0],765);
- if effect then move (biiiigpallette[start],bob2[255],3) else
- move (temp,bob2[255],3);
- start:=start+1;
- if start=6657 then start:=0;
- setallpal (bob2);
- END;
-
-
- {──────────────────────────────────────────────────────────────────────────}
- Procedure Play;
- VAR loop1:integer;
- BEGIN
- start:=256;
- for loop1:=1 to 64 do BEGIN
- fadeupone(loop1);
- drawplasma;
- moveplasma;
- END; { Fade up the plasma }
- while keypressed do readkey;
- Repeat
- shiftpallette;
- drawplasma;
- moveplasma;
- Until keypressed; { Do the plasma }
- move (bob2,bob,768);
- for loop1:=1 to 64 do BEGIN
- fadeupone(64-loop1);
- drawplasma;
- moveplasma;
- END; { fade down the plasma }
- while keypressed do readkey;
- END;
-
- BEGIN
- clrscr;
- writeln ('Hi there ... here is a tut on plasmas! (By popular demand). The');
- writeln ('program will ask you weather you want the Psychadelic effect, in');
- writeln ('which the pallette does strange things (otherwise the pallette');
- writeln ('remains constant), and it will ask weather you want a background');
- writeln ('(a static pic behind the plasma). Try them both!');
- writeln;
- writeln ('The thing about plasmas is that they are very easy to change/modify');
- writeln ('and this one is no exception .. you can even change the background');
- writeln ('with minimum hassle. Try adding and deleting things, you will be');
- writeln ('surprised by the results!');
- writeln;
- writeln ('This is by no means the only way to do plasmas, and there are other');
- writeln ('sample programs out there. Have fun with this one though! ;-)');
- writeln;
- writeln;
- init;
- play;
- asm
- mov ax,0003h
- int 10h
- end;
- Writeln ('All done. This concludes the fifteenth sample program in the ASPHYXIA');
- Writeln ('Training series. You may reach DENTHOR under the names of GRANT');
- Writeln ('SMITH/DENTHOR/ASPHYXIA on the ASPHYXIA BBS.I also occasinally');
- Writeln ('RSAProg, comp.lang.pascal and comp.sys.ibm.pc.demos. E-mail me at :');
- Writeln (' denthor@beastie.cs.und.ac.za');
- Writeln ('The numbers are available in the main text. You may also write to me at:');
- Writeln (' Grant Smith');
- Writeln (' P.O. Box 270');
- Writeln (' Kloof');
- Writeln (' 3640');
- Writeln (' Natal');
- Writeln (' South Africa');
- Writeln ('I hope to hear from you soon!');
- Writeln; Writeln;
- Write ('Hit any key to exit ...');
- readkey;
- END.